package rd.hardcore.engine.datas.streamBoard 
{
	import flash.events.DataEvent;
	import flash.events.ErrorEvent;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.IOErrorEvent;
	import flash.events.ProgressEvent;
	import flash.filesystem.File;
	import flash.filesystem.FileMode;
	import flash.filesystem.FileStream;
	import flash.net.URLLoader;
	import flash.net.URLLoaderDataFormat;
	import flash.net.URLRequest;
	import flash.utils.ByteArray;
	import fr.digitas.flowearth.command.Batcher;
	import fr.digitas.flowearth.net.BatchLoaderItem;
	import fr.digitas.flowearth.net.BatchURLLoaderItem;
	import nochump.util.zip.ZipEntry;
	import nochump.util.zip.ZipFile;
	import rd.hardcore.datas.Track;
	/**
	 * ...
	 * @author Fazermokeur
	 */
	public class StreamBoardInstaller extends EventDispatcher
	{
		
		private var _name:String;
		private var _url:String;
		private var fileCpt:int;
		private var _tab:Array;
		private var streamBoardDescriptor:XML;
		private var bPuce:BatchURLLoaderItem;
		private var bBackground:BatchURLLoaderItem;
		private var bPreview:BatchURLLoaderItem;
		
		public function StreamBoardInstaller(name:String, url:String) 
		{
			_name = name;
			_url = url;
			trace("0:StreamBoard Intaller");
			var l:URLLoader = new URLLoader();
			l.addEventListener(IOErrorEvent.IO_ERROR, handleIOError);
			l.addEventListener(Event.COMPLETE, handleXMLComplete);
			var target:String = _url + _name + ".xml";
			l.load(new URLRequest(target));
		}
		
		private function handleXMLComplete(e:Event):void 
		{
			var l:URLLoader = e.currentTarget as URLLoader;
			try {
				var tracks:XML = new XML(l.data);
			}catch (e:Error) {
				dispatchEvent(new ErrorEvent(ErrorEvent.ERROR));
				return;
			}
			
			var node:XML;
			_tab = []
			var b:Batcher = new Batcher();
			b.addEventListener(Event.COMPLETE, handleAllH4rdcoreLoaded);
			b.addEventListener(ProgressEvent.PROGRESS, handleProgress);
			var bi:BatchURLLoaderItem;
			fileCpt = 0;
			for each (node in tracks.files.file) 
			{
				bi = new BatchURLLoaderItem(new URLRequest(_url + "" + node));
				bi.dataFormat = URLLoaderDataFormat.BINARY;
				_tab.push(bi);
				bi.addEventListener(Event.COMPLETE, handleComplete);
				b.addItem(bi);
				fileCpt++;
			}
			if (tracks.navMedia.toString().length > 0) {
				bPuce = new BatchURLLoaderItem(new URLRequest(_url + "" + tracks.navMedia));
				bPuce.dataFormat = URLLoaderDataFormat.BINARY;
				bPuce.addEventListener(Event.COMPLETE, puceLoaded);
				b.addItem(bPuce);
			}
			if (tracks.backgroundMedia.toString().length > 0) {
				bBackground = new BatchURLLoaderItem(new URLRequest(_url + "" + tracks.backgroundMedia));
				bBackground.dataFormat = URLLoaderDataFormat.BINARY;
				bBackground.addEventListener(Event.COMPLETE, backgroundLoaded);
				b.addItem(bBackground);
			}
			if (tracks.previewMedia.toString().length > 0) {
				bPreview = new BatchURLLoaderItem(new URLRequest(_url + "" + tracks.previewMedia));
				bPreview.dataFormat = URLLoaderDataFormat.BINARY;
				bPreview.addEventListener(Event.COMPLETE, previewLoaded);
				b.addItem(bPreview);	
			}
			
			streamBoardDescriptor = <data></data>;
			streamBoardDescriptor.appendChild( tracks.tracks );
			streamBoardDescriptor.appendChild( tracks.navMedia );
			streamBoardDescriptor.appendChild( tracks.previewMedia );
			streamBoardDescriptor.appendChild( tracks.backgroundMedia );
			
			b.start();
		}
		
		
		private function puceLoaded(e:Event):void 
		{
			bPuce.removeEventListener(Event.COMPLETE, puceLoaded);
			writeFile(streamBoardDescriptor.navMedia, bPuce.data);
		}
		
		private function backgroundLoaded(e:Event):void 
		{
			bBackground.removeEventListener(Event.COMPLETE, backgroundLoaded);
			writeFile(streamBoardDescriptor.backgroundMedia, bBackground.data);
		}
		
		private function previewLoaded(e:Event):void 
		{
			bPreview.removeEventListener(Event.COMPLETE, previewLoaded);
			writeFile(streamBoardDescriptor.previewMedia, bPreview.data);
		}
		
		private function handleComplete(e:Event):void 
		{
			(e.currentTarget as EventDispatcher).removeEventListener(Event.COMPLETE, handleComplete);
		}
		
		private function handleProgress(e:ProgressEvent):void 
		{
			//trace("0:loading... "+(e.bytesLoaded/e.bytesTotal*100)+"%");
		}
		
		private function handleAllH4rdcoreLoaded(e:Event):void 
		{
			var b:Batcher = (e.currentTarget as Batcher);
			b.removeEventListener(Event.COMPLETE, handleAllH4rdcoreLoaded);
			b.removeEventListener(ProgressEvent.PROGRESS, handleProgress);
			for (var i:int = 0; i < fileCpt; i++) 
			{
				deZipAndWrite(_tab[i] as BatchURLLoaderItem);
			}
			
			writeXML();
			
			trace("2:StreamBoardSynchroEvent.STREAMBOARD_SYNCHONIZED");
			dispatchEvent(new StreamBoardSynchroEvent(StreamBoardSynchroEvent.STREAMBOARD_SYNCHONIZED, _name));
		}
		
		private function deZipAndWrite(bi:BatchURLLoaderItem):void
		{
			var zipFile:ZipFile = new ZipFile(bi.data);
			
			var t:Track = new Track();
			
			for (var i:int = 0; i < zipFile.entries.length; i++)
			{
				var entry:ZipEntry = zipFile.entries[i];
				
				// extract the entry's data from the zip
				var data:ByteArray = zipFile.getInput(entry);
				
				
				/* JPG */
				if ( entry.name.search("jpg") > 0 )
				{
					writeFile(entry.name, data);
				}
				
				/* MP3 */
				if ( entry.name.search("mp3") > 0 )
				{
					writeFile(entry.name, data);
				}
				
			}
		}
		
		private function writeFile(entryName:String, data:ByteArray):void
		{
			var fs:FileStream = new FileStream();
			var uri:String = "boards/" + _name + "/" + entryName;
			var f:File = File.applicationStorageDirectory.resolvePath(uri);
			
			fs.open(f, FileMode.WRITE);
			try {
				fs.writeBytes(data);
			}catch (e:Error) {
				trace(e.errorID + " :: " + e.message);
			}
			fs.close();
		}
		
		private function writeXML():void
		{
			var fs:FileStream = new FileStream();
			var uri:String = "boards/" + _name + "/" + _name + ".xml";
			var f:File = File.applicationStorageDirectory.resolvePath(uri);
			
			fs.open(f, FileMode.WRITE);
			
			try {
				fs.writeUTFBytes(streamBoardDescriptor);
			}catch (e:Error) {
				trace(e.errorID + " :: " + e.message);
			}
			
			fs.close();
		}
		
		private function handleIOError(e:IOErrorEvent):void 
		{
			throw new Error("File or connexion doesn't exist ");
			b.removeEventListener(Event.COMPLETE, handleAllH4rdcoreLoaded);
			b.removeEventListener(ProgressEvent.PROGRESS, handleProgress);
		}
		
	}

}